package com.farm.aop;

import com.alibaba.fastjson.JSON;
import com.farm.common.States;
import com.farm.common.esIndex;
import com.farm.mapper.CommitMapper;
import com.farm.mapper.PolicyMapper;
import com.farm.mapper.VideoMapper;
import com.farm.pojo.*;
import com.farm.pojo.Vo.ReplyVo;
import com.farm.service.PolicyService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;

@Component
@Aspect
@Slf4j
public class updateAspect {
    // 切入点表达式
    @Pointcut("@annotation(com.farm.aop.aopUpdate)")
    public void updatePointcut(){}
    
    @Autowired
    private PolicyMapper policyMapper;

    @Autowired
    private CommitMapper commitMapper;
    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private RestHighLevelClient client;

    /**
     * 给管理员审核的时候添加此注解
     * 如果状态为一再更新es数据表，如果不是则执行删除操作
     * 更新可以根据id字段查询数据库的值，然后进行插入操作、
     * 可以通过获取其方法名进行判断操作的表
     * 删除的话则根据id号来删除，不存在也没关系es不会报错
     * @param joinPoint
     */
    @AfterReturning("updatePointcut()")
    public void updateAop(JoinPoint joinPoint){

        // 获取传入参数的签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取注解对象
        aopUpdate aopAnnotation = signature.getMethod().getAnnotation(aopUpdate.class);

        // 操作政策表
        // 获取数据库操作类型
        if (aopAnnotation.TypeValue() == Type.POLICY){
            Policy policy = (Policy) joinPoint.getArgs()[0];

            if (policy.getState() == States.DISABLE || aopAnnotation.OperationValue() == Operation.DELETE){
                // 删除数据
                DeleteRequest deleteRequest =
                        new DeleteRequest(esIndex.policy, String.valueOf(policy.getId()));
                try {
                    client.delete(deleteRequest, RequestOptions.DEFAULT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 更新es数据
            else {
                // 查询数据库数据
                Policy policy1 = policyMapper.selectById(policy.getId());
                PolicyEs policyEs = new PolicyEs(policy1);
                System.out.println("我在更新政策数据：" + policyEs);
                String json = JSON.toJSONString(policyEs);
                // 插入数据
                IndexRequest indexRequest = new IndexRequest(esIndex.policy)
                        .id(policyEs.getId().toString())
                        .source(json, XContentType.JSON);
                try {
                    client.index(indexRequest, RequestOptions.DEFAULT);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return;
        }


        // 操作内容问答
        if (aopAnnotation.TypeValue() == Type.COMMITED){
            if(aopAnnotation.OperationValue() == Operation.DELETE){
                Long id = (Long) joinPoint.getArgs()[0];
                // 删除数据
                deleteEsById(esIndex.commit, id);
            }else {
                Commited commited = (Commited) joinPoint.getArgs()[0];
                if (commited.getState() == States.DISABLE) {
                    // 删除数据
                    deleteEsById(esIndex.commit, commited.getCommitId());
                }else {
                    // 查询数据库数据
                    Commited commited1 = commitMapper.selectById(commited.getCommitId());
                    CommitEs commitEs = new CommitEs(commited1);
                    String json = JSON.toJSONString(commitEs);
                    // 插入数据
                    IndexRequest indexRequest = new IndexRequest(esIndex.commit)
                            .id(commitEs.getCommitId().toString())
                            .source(json, XContentType.JSON);
                    try {
                        client.index(indexRequest, RequestOptions.DEFAULT);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }

                }
            return;
            }


        // 操作视频
        if (aopAnnotation.TypeValue() == Type.VIDEO){
            Video video = (Video) joinPoint.getArgs()[0];
            if (video.getState() == States.DISABLE || aopAnnotation.OperationValue() == Operation.DELETE){
                // 删除数据
                DeleteRequest deleteRequest =
                        new DeleteRequest(esIndex.video, String.valueOf(video.getVideoId()));
                try {
                    client.delete(deleteRequest, RequestOptions.DEFAULT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 更新es数据
            else {
                // 查询数据库数据
                Video video1 = videoMapper.selectById(video.getVideoId());
                videoEs videoEs = new videoEs();
                BeanUtils.copyProperties(video1, videoEs);
                String json = JSON.toJSONString(videoEs);
                // 插入数据
                IndexRequest indexRequest = new IndexRequest(esIndex.video)
                        .id(videoEs.getVideoId().toString())
                        .source(json, XContentType.JSON);
                try {
                    client.index(indexRequest, RequestOptions.DEFAULT);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return;
        }



        
        // 获取操作类名
//        String classsName = joinPoint.getTarget().getClass().getName();
//        // 获取方法参数
//        Object[] args = joinPoint.getArgs();
////        String classString = Arrays.toString(args).substring(Arrays.toString(args).lastIndexOf("."));
////        log.info("类名是" + classString);
//        log.info("方法的传入参数：" + Arrays.toString(args));
//        log.info(classsName);
//        log.info("我这里是aop: ");
    }


    public void deleteEsById(String deleteOperation, Long id){
        DeleteRequest deleteRequest =
                new DeleteRequest(deleteOperation, String.valueOf(id));
        try {
            client.delete(deleteRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
